﻿using AutoMapper;
using SIG.Infrastructure.Captcha;
using SIG.Infrastructure.Configs;
using SIG.Infrastructure.Helper;
using SIG.InputModel.Front.Identity;
using SIG.Model.Enum;
using SIG.Model.Identity;
using SIG.Model.ViewModel.Identity;
using SIG.Resources.Front;
using SIG.Service;
using SIG.Service.Identity;
using SIG.ViewModel;
using System;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using System.Web;
using System.Web.Hosting;
using System.Web.Mvc;
using System.Web.Security;

namespace SIG.WebMVC.Controllers
{
    public class AccountController : BaseController
    {
        IUserService _userService;
        IUserSafetyService _userSafetyService;
        IEmailTemplateService _templateService;
        Infrastructure.Email.IEmailService _emailService;
        IMapper _mapper;
        public AccountController(IUserService UserService, IUserSafetyService userSafetyService, IEmailTemplateService templateService, Infrastructure.Email.IEmailService emailService, IMapper mapper)
        {
            _userService = UserService;
            _userSafetyService = userSafetyService;
            _templateService = templateService;
            _emailService = emailService;
            _mapper = mapper;
        }
        public CaptchaImageResult ShowCaptchaImage()
        {
            return new CaptchaImageResult();
        }

        [Authorize]
        public ActionResult Index()
        {
            return View();
        }

        [HttpGet]
        [Authorize]
        public async Task<ActionResult> MyProfile()
        {
            var user = await _userService.GetUserByName(User.Identity.Name);
            if (user == null)
            {
                return HttpNotFound();
            }
            ViewData["PhotoUrl"] = string.IsNullOrEmpty(user.PhotoUrl) ? SettingsManager.User.DefaultAvatar : user.PhotoUrl;
            var Profiles = _mapper.Map<ProfileIM>(user);
            return View(Profiles);
        }


        // webuploader upload file

        [HttpPost]
        public ActionResult UpLoadProcess(string id, string name, string path, string type, string lastModifiedDate, int size, HttpPostedFileBase file)
        {
            string filePathName = string.Empty;

            string dir = string.IsNullOrEmpty(path) ? "~/Content/Public/Img/Avatars" : path;
            string localPath = HostingEnvironment.MapPath(dir);
            // string localPath = Path.Combine(HttpRuntime.AppDomainAppPath, "Uploads");
            if (Request.Files.Count == 0)
            {
                return Json(new { jsonrpc = 2.0, error = new { code = 102, message = "保存失败" }, id = "id" });
            }

            string ex = Path.GetExtension(file.FileName);
            filePathName = Guid.NewGuid().ToString("N") + ex;
            if (Directory.Exists(localPath))
            {
                Directory.CreateDirectory(localPath);
            }
            var savePath = Path.Combine(localPath, filePathName);         
            file.SaveAs(savePath);

            var user = _userService.GetById(User.UserId);
            if (!string.IsNullOrEmpty(user.PhotoUrl))
                System.IO.File.Delete(HostingEnvironment.MapPath(user.PhotoUrl));

            var photoUrl = Path.Combine(SettingsManager.User.AvatarDir, filePathName);
            user.PhotoUrl = photoUrl;
            _userService.Update(user);

            return Json(new
            {
                jsonrpc = "2.0",
                id = id,
                filePath = photoUrl
            });

        }



        [HttpPost]
        [ValidateAntiForgeryToken]
        public JsonResult MyProfile([Bind(Include = "Id,Email,RealName,Birthday,IsActive,Gender,QQ,Mobile")] ProfileIM profile)
        {
            if (!ModelState.IsValid)
            {
                var errorMes = GetModelErrorMessage();
                AR.Setfailure(errorMes);
                return Json(AR, JsonRequestBehavior.DenyGet);
            }

            var user = _userService.GetById(profile.Id);
            if (user == null)
            {
                AR.Setfailure("不存在此用户！");
                return Json(AR, JsonRequestBehavior.DenyGet);
                // return Json(false, JsonRequestBehavior.DenyGet);
            }
            try
            {
                user.Email = profile.Email;
                user.RealName = profile.RealName;
                user.IsActive = profile.IsActive;
                //user.DepartmentId = profile.DepartmentId;
                //user.PositionId = profile.PositionId;
                user.QQ = profile.QQ;
                user.Mobile = profile.Mobile;
                user.Gender = profile.Gender;
                user.Birthday = profile.Birthday;

                _userService.Update(user);

                AR.SetSuccess("操作成功！");
                return Json(AR, JsonRequestBehavior.DenyGet);
            }
            catch (Exception ex)
            {
                AR.Setfailure(ex.Message);
                return Json(AR, JsonRequestBehavior.DenyGet);
            }

        }
        public JsonResult IsEmailUniqueAtEdit(string email, Guid id)
        {
            var result = _userService.IsEmailUniqueAtEdit(email, id);

            return result
                ? Json(true, JsonRequestBehavior.AllowGet)
                : Json(false, JsonRequestBehavior.AllowGet);
        }

        [HttpGet]
        public ActionResult Register()
        {
            return View();
        }

        [HttpPost]
        [AllowAnonymous]
        [ValidateAntiForgeryToken]
        public ActionResult Register(RegisterIM model)
        {
            if (!ModelState.IsValid)
            {
                var errorMes = GetModelErrorMessage();
                AR.Setfailure(errorMes);
                return Json(AR, JsonRequestBehavior.DenyGet);
            }


            var result =_userService.Register(model.UserName,model.Email,model.Password,model.DisplayName);

            if (result == 1)
            {
                AR.Setfailure(Messages.CannotRegisterEmail);
                return Json(AR, JsonRequestBehavior.DenyGet);
            }

            if (result == 2)
            {
                AR.Setfailure(Messages.CannotRegisterUserName);
                return Json(AR, JsonRequestBehavior.DenyGet);
            }
            

            AR.SetSuccess(string.Format(Messages.AlertCreateSuccess,  Titles.RegisterUser));
            return Json(AR, JsonRequestBehavior.DenyGet);
        }

        public async Task<JsonResult> IsUserNameUnique(string UserName)
        {
            var user = await _userService.GetUserByName(UserName);

            return user == null
                ? Json(true, JsonRequestBehavior.AllowGet)
                : Json(false, JsonRequestBehavior.AllowGet);
        }

        public async Task<JsonResult> IsEmailUnique(string Email)
        {
            var user = await _userService.GetUserByEmail(Email);

            return user == null
                ? Json(true, JsonRequestBehavior.AllowGet)
                : Json(false, JsonRequestBehavior.AllowGet);
        }

        //
        // GET: /Account/Login      
        public ActionResult Login(string returnUrl)
        {
            ViewBag.ReturnUrl = returnUrl;
            return View();
        }

        [HttpPost]       
        [ValidateAntiForgeryToken]
        public async Task<ActionResult> Login(LoginIM model, string returnUrl)
        {
            if (ModelState.IsValid)
            {
                if(Session["SigCaptcha"]!=null && Session["SigCaptcha"].ToString().ToLower() != model.CaptchaText.ToLower())
                {
                    ModelState.AddModelError(string.Empty, "验证码不正确!");
                    return View(model);
                }
              
                var user = await _userService.SignIn(model.UserName,model.Password);
                //var user = db.Users.Where(u => u.Username == model.UserName && u.PasswordHash == model.Password).FirstOrDefault();
                if (user != null)
                {
                    if (!user.IsActive)
                    {
                        ModelState.AddModelError(string.Empty, "此帐号已经被停用!");
                        return View(model);
                    }
                    var roles = user.Roles.Select(m => m.RoleName).ToArray();   

                    user.LastActivityDate = DateTime.Now;
                    _userService.Update(user);

                    //设置cookies
                    _userService.SetUserCookies(model.RememberMe, user);

                    if (roles.Contains("系统管理员") || roles.Contains("管理员"))
                    {
                        return RedirectToAction("Index", "Home", new { area = "Admin" });
                    }
                    else if (roles.Contains("User"))
                    {
                        return RedirectToAction("Index", "User");
                    }
                    else
                    {
                        return RedirectToAction("Index", "Home");
                    }
                }

                ModelState.AddModelError(string.Empty, "无效的用户名或密码！");
            }

            return View(model);
        }


        [Authorize]
        public ActionResult UpdatePWD()
        {
            ChangePasswordIM vm = new ChangePasswordIM();
            return View(vm);
        }


        [Authorize]
        [HttpPost]
        public ActionResult UpdatePWD(ChangePasswordIM vm)
        {
            if (!ModelState.IsValid)
            {
                var errorMes = GetModelErrorMessage();
                AR.Setfailure(errorMes);
                return Json(AR, JsonRequestBehavior.DenyGet);
            }

            var result = _userService.ChangePassword(User.UserId, vm.OldPassword, vm.NewPassword);
          
            if (result == 1)
            {
                AR.Setfailure(Messages.NoUser);
                return Json(AR, JsonRequestBehavior.DenyGet);
            }
            if (result == 2)
            {
                AR.Setfailure(Messages.PasswordError);
                return Json(AR, JsonRequestBehavior.DenyGet);
            }

            AR.SetSuccess(string.Format(Messages.AlertUpdateSuccess, Labels.Password));
            return Json(AR, JsonRequestBehavior.DenyGet);

        }


      

        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult LogOut()
        {
            FormsAuthentication.SignOut();
            return RedirectToAction("Index", "Home", new { area=""});
        }

        [HttpGet]
        public ActionResult FindPassword()
        {
            return View();
        }

        [HttpPost]
        [ValidateAntiForgeryToken]
        public async Task<ActionResult> FindPassword(FindPasswordIM vm)
        {
            var user = await _userService.GetUserByName(vm.UserName);
            if (user == null)
            {
                AR.Setfailure(Messages.NoUser);
                return Json(AR, JsonRequestBehavior.DenyGet);
            }

            var template = _templateService.GetEmailTemplateByTemplateNo("T002");
            if (template == null)
            {
                AR.Setfailure(string.Format(Messages.NoEmailTemplate, "T002"));
                return Json(AR, JsonRequestBehavior.DenyGet);
            }

            try
            {
                var emailAccount = template.EmailAccount;

                var type = EmailType.RESETPASSWORD;
                var code = IdentityGenerator.SequentialGuid();
                var createdDate = DateTime.Now;


                var userSafety = new UserSafety()
                {
                    Username = vm.UserName,
                    Code = code,
                    EmailType = type,
                    Timeout = 30,
                    CreatedDate = createdDate
                };
                _userSafetyService.Create(userSafety);

                var url = Url.Action("ResetPassowrd","Account", new { type = EmailType.RESETPASSWORD, code = code }, Request.Url.Scheme);

                var emailBody = _templateService.ReplaceTemplate(template.Body);
                emailBody = emailBody.Replace("{ResetPasswordURL}", url);

                _emailService.SendMail(SettingsManager.Site.SiteName, user.Email, string.Empty,
                    template.Subject, emailBody, emailAccount.SmtpServer, emailAccount.Email, SettingsManager.Site.SiteName,
                    emailAccount.UserName, EncryptionHelper.Decrypt(emailAccount.Password), emailAccount.Port, emailAccount.EnableSsl);


                AR.SetSuccess(Messages.ResetPasswordEmailSentSuccess);
                return Json(AR, JsonRequestBehavior.DenyGet);
            }
            catch(Exception er)
            {
                AR.Setfailure(er.Message);
                return Json(AR, JsonRequestBehavior.DenyGet);
            }           
           
        }

        [HttpGet]
        public ActionResult ResetPassowrd(EmailType type,string code)
        {
            Guid guidOutput;

            bool isValid = Guid.TryParse(code, out guidOutput);
            if (!isValid)
            {
                ViewData["Error"] = "无效的请求！";
            }

            var usersafety = _userSafetyService.FindBy(m => m.EmailType == type && m.Code == guidOutput).FirstOrDefault();
            if (usersafety == null)
            {
                ViewData["Error"] = "无效的请求！";
            }

            if(usersafety.CreatedDate.AddMinutes(usersafety.Timeout) < DateTime.Now)
            {
                ViewData["Error"] = "链接已过期，无效的请求！";
            }


            var resetPassword = new ResetPasswordIM
            {
                UserName = usersafety.Username
            };

            return View(resetPassword);
        }

        [HttpPost]
        [ValidateAntiForgeryToken]
        public async Task<ActionResult> ResetPassword(ResetPasswordIM vm)
        {
            if (!ModelState.IsValid)
            {
                var errorMes = GetModelErrorMessage();
                AR.Setfailure(errorMes);
                return Json(AR, JsonRequestBehavior.DenyGet);
            }

            var result = await _userService.ResetPassword(vm.UserName, vm.Password);
            if (result)
            {
                AR.SetSuccess(string.Format(Messages.AlertUpdateSuccess, Labels.Password));
                return Json(AR, JsonRequestBehavior.DenyGet);
            }
           
            AR.Setfailure(Messages.AlertUpdateFailure);
            return Json(AR, JsonRequestBehavior.DenyGet);     

          
        }
    }
}